//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __PSEUDOMODULE_H__
#define __PSEUDOMODULE_H__

#include <elasys_server.h>
#include <interlocked.h>
#include "pobject.h"

class CPseudoModule: public PseudoObject, public IModule
{
public:
    PInterface GetObject() { return (IModule *) this; }
    Boolean Compare(PVoid pCompareData)
    { return (m_pProxy == (IModule *)pCompareData) ? TRUE : FALSE; }

public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI GetBaseAddress(
        /* [out] */ Address * pBase);

    CARAPI GetEntryPointAddress(
        /* [out] */ Address * pDllMainStartup);

    CARAPI GetMemorySize(
        /* [out] */ MemorySize * pSize);

    CARAPI GetName(
        /* [out] */ WStringBuf * name);

    CARAPI GetFullPath(
        /* [out] */ WStringBuf * name);

    CARAPI GetProcAddressByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI GetProcAddressByOrdinal(
        /* [in] */ Int32 ordinal,
        /* [out] */ Address * pAddress);

    CARAPI GetResourceSection(
        /* [out] */ Address * pAddress);

    CARAPI GetSectionByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI FindResource(
        /* [in] */ WString wsName,
        /* [in] */ WString wsType,
        /* [out] */ Address * pAddress,
        /* [out] */ MemorySize * pSize);

public:
    CPseudoModule(ProcessId processId, IModule * pProxy)
                    : m_processId(processId),
                      m_pProxy(pProxy),
                      m_hLock(NULL) {}

    virtual ~CPseudoModule();

    ECode Initialize();

private:
    ProcessId m_processId;
    IModule * m_pProxy;
    PVoid     m_hLock;

private:
    Interlocked m_cRef;
};

class CPseudoModuleFactory: public PseudoObjectFactory
{
public:
    ECode CreateObject(
        /* [out] */ PseudoObject ** ppPseudoObject);

    Boolean Compare(
        /* [in] */ PseudoObject * pPseudoObject)
    { return pPseudoObject->Compare((PVoid)m_pProxy); }

    PseudoObjectType GetType() { return PseudoObjectType_Module; }

public:
    CPseudoModuleFactory(ProcessId processId, IModule * pProxy)
                       : m_processId(processId),
                         m_pProxy(pProxy) {}

private:
    ProcessId m_processId;
    IModule * m_pProxy;
};

#endif //__PSEUDOMODULE_H__

